#include "stdlib.h"
#include "string.h"
#include <hidef.h> /* for EnableInterrupts macro */
#include "Headers/derivative.h" /* include peripheral declarations */
#include "Headers/define.h"
#include "Headers/RF.h"
#include "Headers/SPI.h"
#include "Headers/micelaneous.h"
/*
* this function is for send a string by rf (you must to set up the packet transmit)
* parameters
*          dato-------> is the pointer to the data to be send
* return 1 if some error and 0 if the string wars sent ok
* NOTE this function put in the dato a check sum to be send along with the string
*/
char TX_pkt_rf(char *dato){
  char aux, rta_fc = 0, i = 0;
  int trying = 0;
  word checksum = 0;
  control_a &= ~(Control_A_rx_strm | Control_A_tx_strm | Control_A_tmr_trig_en);
  control_b &= ~Control_B_use_strm_mode;
  SendCommand(Control_A, control_a);      
  SendCommand(Control_B, control_b);
  control_a |= Control_A_tx_send_mask;
  SendCommand(Control_A, control_a);
  
  command_modem = ReadCommand(TX_Pkt_Ctl);
  command_modem &= 0xff00;
  while(dato[i] != 0X00){
    checksum += dato[i];
    i++; 
  }
  if(i%2 != 0){
    dato[i++] = 0x20;
    checksum += dato[i-1];
  }
  if(i <= 118){
    dato[i++] = checksum >> 8;
    dato[i++] = checksum & 0x00ff;
    aux = i + 2;
    SendCommand(TX_Pkt_Ctl, command_modem|aux);
    SPI_recursive(TX_Pkt_RAM, dato, 0, i);
    control_a |= Control_A_xcvr_seq_Tx;
    SendCommand(Control_A, control_a);
    RXTXEN = 1;
    do{
      irq_status = ReadCommand(IRQ_Status);
      irq_status &= bit6;
      __RESET_WATCHDOG();
      trying++;
    }while(irq_status != bit6 && trying < 1000);
  }
  if(trying >= 1000) rta_fc = 1;
  control_a &= Control_A_xcvr_seq_Idle;
  control_a &= ~Control_A_tx_send_mask;
  SendCommand(Control_A, control_a);
  RXTXEN = 0;
  return rta_fc;
  
}
/*
* this function is for receive a string by rf (you must to set up the packet transmit)
* parameters
*          dato-------> is the pointer to the data to be read
* return 1 if was some error and 0 for a string read
* NOTE this function check the check sum received and make a new one if this two doesn't match at all the pointer is cleaned
*/
char RX_pkt_rf(char *dato){
  
  char i = 0, *aux, length = 0, rta_fc = 1;
  int  trying = 0;
  word checksum = 0;
  aux = malloc(125);
  control_a &= ~(Control_A_rx_strm | Control_A_tx_strm | Control_A_tmr_trig_en);
  control_b &= ~Control_B_use_strm_mode;
  SendCommand(Control_A, control_a);      
  SendCommand(Control_B, control_b);
  __RESET_WATCHDOG();
  control_a |= Control_A_rx_rcvd_mask;
  SendCommand(Control_A, control_a);
  control_a |= Control_A_xcvr_seq_Rx;
  SendCommand(Control_A, control_a);
  RXTXEN = 1;
  __RESET_WATCHDOG();
  do{
    irq_status = ReadCommand(IRQ_Status);
    Delay(1);
    __RESET_WATCHDOG();
    trying++;
  }while((irq_status & bit7) != bit7 && trying < 2000);
  rx_status = ReadCommand(RX_Status);
  for(i = 0; i < 125; i++)dato[i] = 0;
  if((irq_status & bit7) == bit7){
    if((irq_status & bit0) == bit0){
       rx_pkt_latch = (rx_status & 0x00ff);
       cca_final = rx_status >> 8;
       if(rx_pkt_latch > 2){
        SPI_recursive(RX_Pkt_RAM, aux, 1, rx_pkt_latch);
        for(i = 0; i < rx_pkt_latch-2; i++)dato[i] = aux[i+2];
        length = 0;
        while(length < rx_pkt_latch-4){
          checksum += dato[length];
          length++; 
        }
        if(dato[length] != (checksum >> 8) || dato[length+1] != (checksum & 0x00ff))for(i = 0; i < rx_pkt_latch-2; i++)dato[i] = 0;
        dato[length] = 0;
        dato[length+1] = 0;
        if(dato[length-1] == 0x20)dato[length-1] = 0;
        rta_fc = 0;
      }
    }
  }
  __RESET_WATCHDOG();
  control_a &= ~Control_A_rx_rcvd_mask;
  SendCommand(Control_A, control_a);
  control_a &= Control_A_xcvr_seq_Idle;
  SendCommand(Control_A, control_a);
  RXTXEN = 1;
  __RESET_WATCHDOG();
  free(aux);
  return rta_fc;
}
/*
* this function is for configure the packet transceiver and the 
* frequency of the RF
* parameters
*          chanel ------------> is to chose the frequency of the RF
* Note: Acording to the protocol ZigBee Fc = 2405 + 5*(K-11), where 11 >= k <= 26
*/
void Set_up_pkt(char chanel){
  if(chanel == 11){
    SendCommand(LO1_Int_Div, 0x0F95);
    SendCommand(LO1_Num, 0x5000);
  }else if(chanel == 12){
    SendCommand(LO1_Int_Div, 0x0F95);
    SendCommand(LO1_Num, 0xA000);
  }else if(chanel == 13){
    SendCommand(LO1_Int_Div, 0x0F95);
    SendCommand(LO1_Num, 0xF000);
  }else if(chanel == 14){
    SendCommand(LO1_Int_Div, 0x0F96);
    SendCommand(LO1_Num, 0x4000);
  }else if(chanel == 15){
    SendCommand(LO1_Int_Div, 0x0F96);
    SendCommand(LO1_Num, 0x9000);
  }else if(chanel == 16){
    SendCommand(LO1_Int_Div, 0x0F96);
    SendCommand(LO1_Num, 0xE000);
  }else if(chanel == 17){
    SendCommand(LO1_Int_Div, 0x0F97);
    SendCommand(LO1_Num, 0x3000);
  }else if(chanel == 18){
    SendCommand(LO1_Int_Div, 0x0F97);
    SendCommand(LO1_Num, 0x8000);
  }else if(chanel == 19){
    SendCommand(LO1_Int_Div, 0x0F97);
    SendCommand(LO1_Num, 0xD000);
  }else if(chanel == 20){
    SendCommand(LO1_Int_Div, 0x0F98);
    SendCommand(LO1_Num, 0x2000);
  }else if(chanel == 21){
    SendCommand(LO1_Int_Div, 0x0F98);
    SendCommand(LO1_Num, 0x7000);
  }else if(chanel == 22){
    SendCommand(LO1_Int_Div, 0x0F98);
    SendCommand(LO1_Num, 0xC000);
  }else if(chanel == 23){
    SendCommand(LO1_Int_Div, 0x0F99);
    SendCommand(LO1_Num, 0x1000);
  }else if(chanel == 24){
    SendCommand(LO1_Int_Div, 0x0F99);
    SendCommand(LO1_Num, 0x6000);
  }else if(chanel == 25){
    SendCommand(LO1_Int_Div, 0x0F99);
    SendCommand(LO1_Num, 0xB000);
  }else if(chanel == 26){
    SendCommand(LO1_Int_Div, 0x0F9A);
    SendCommand(LO1_Num, 0x0000);
  }else{
    // this is the default value for the RF
    SendCommand(LO1_Int_Div, 0x0F95);
    SendCommand(LO1_Num, 0x5000);
  }
  RXTXEN = 0;
  control_a &= Control_A_xcvr_seq_Idle;
  control_a &= ~Control_A_tmr_trig_en;
  control_a &= ~Control_A_rx_strm;
  control_a &= ~Control_A_tx_strm;
  control_b &= ~Control_B_use_strm_mode;
 
  control_b |= Control_B_tx_done_mask;
  control_b |= Control_B_rx_done_mask;
  
  control_c |= Control_C_gpio_alt_en;
  SendCommand(Control_A, control_a);
  SendCommand(Control_B, control_b);
  SendCommand(Control_C, control_c);

}